Skip to content

Conversation

@carlos-granados
Copy link

@carlos-granados carlos-granados commented Jan 16, 2026

Adds 6 new functions which can be used to work with string suffixes and prefixes:

function str_prefix_ensure(string $prefix, string $subject): string
function str_suffix_ensure(string $suffix, string $subject): string

Add a prefix or suffix to a string only if the string does not yet have it

function str_prefix_remove(string $prefix, string $subject): string
function str_suffix_remove(string $suffix, string $subject): string

Remove a prefix or suffix from a string if the string has it

function str_prefix_replace(string $prefix, string $replace, string $subject): string
function str_suffix_replace(string $suffix, string $replace, string $subject): string

Replace a prefix or suffix in a string if the string has it

@iluuu1994
Copy link
Member

Hi @carlos-granados. Thanks for your proposal. I think the addition of new string functions is controversial enough to warrant an RFC. See https://wiki.php.net/rfc/howto. I'm foreseeing some disagreements on naming / namespacing, among other things. The add_{suffix,prefix} functions are also pretty much pointless, unless you're working with higher order functions I guess.

@carlos-granados
Copy link
Author

Hi @carlos-granados. Thanks for your proposal. I think the addition of new string functions is controversial enough to warrant an RFC. See https://wiki.php.net/rfc/howto. I'm foreseeing some disagreements on naming / namespacing, among other things. The add_{suffix,prefix} functions are also pretty much pointless, unless you're working with higher order functions I guess.

Thank @iluuu1994 yes, I was planning to create an RFC and in fact I did not intend to create this PR. I wanted to first create it in my fork but it seems that somehow I made a mistake and created it here. Now that it is created I'll leave it here.

@blar
Copy link
Contributor

blar commented Jan 22, 2026

The parameter order should be (in my opinion) ($subject, $prefix) and ($subject, $suffix) to maintain consistency with the existing str_* family:

  • str_starts_with(string $haystack, string $needle)
  • str_ends_with(string $haystack, string $needle)
  • str_contains(string $haystack, string $needle)

Arguments for $subject first:

  1. Consistency: All three existing str_* functions from PHP 8.0 use this order
  2. Readability: Reads naturally as "string X ensure prefix Y" vs. "prefix Y ensure on string X"
  3. Potential future extensions (wish str_starts_with accepted string|array $needle #11267): str_starts_with($string, ["foo", "bar"]) is far clearer than str_starts_with(["foo", "bar"], $string). Same applies here: str_prefix_ensure($path, ["/", "\\"]) vs. the confusing str_prefix_ensure(["/", "\\"], $path)
  4. Method chaining: Future OOP string methods would use $string->ensurePrefix($prefix), not $prefix->ensureOn($string)
  5. Named parameters: str_prefix_ensure(subject: $path, prefix: '/') is clearer than str_prefix_ensure(prefix: '/', subject: $path)
  6. Future options parameter: This PR's test cases already hint at potential extensions (e.g., handling multiple occurrences). The typical pattern would be $haystack, $needle, $options - not $needle, $haystack, $options

@carlos-granados carlos-granados force-pushed the suffix-prefix-functions branch from b9e8c52 to e004c00 Compare January 22, 2026 18:24
@thg2k
Copy link
Contributor

thg2k commented Jan 29, 2026

@carlos-granados What's the benefit of having these functions in the core instead of userspace? Execution speed?

@carlos-granados
Copy link
Author

carlos-granados commented Jan 29, 2026

@carlos-granados What's the benefit of having these functions in the core instead of userspace? Execution speed?

@thg2k you'll get a small performance increase but the main benefits are:

  • Code that is shorter and clearer
  • Readability / intent: “what” is expressed directly, not reconstructed from if + str_starts_with() / str_ends_with() + substr.
  • Consistency: everyone gets the same semantics for edge cases (empty prefix/suffix, longer-than-subject checks, binary strings).
  • Less error-prone code: avoids off-by-one length mistakes and duplicated conditional logic.

All of this in functions which are available in the core, without having to define them or import them in every project.

You could ask the same about the str_starts_with, str_ends_with and str_contains functions. The same reasons to define them in the core intead of user space apply here

You can read more about this in the RFC:
https://wiki.php.net/rfc/prefix_suffix_functions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants